#include <glib-object.h>

void everymat_void();

gboolean everymat_pass_bool(gboolean arg);
gint8 everymat_pass_gint8(gint8 arg);
guint8 everymat_pass_guint8(guint8 arg);
gint16 everymat_pass_gint16(gint16 arg);
guint16 everymat_pass_guint16(guint16 arg);
gint32 everymat_pass_gint32(gint32 arg);
guint32 everymat_pass_guint32(guint32 arg);
gint64 everymat_pass_gint64(gint64 arg);
guint64 everymat_pass_guint64(guint64 arg);
gfloat everymat_pass_gfloat(gfloat arg);
gdouble everymat_pass_gdouble(gdouble arg);
char * everymat_pass_string(char *arg);
GType everymat_pass_gtype(GType arg);
GObject * everymat_pass_gobject(GObject *arg);

void everymat_pass_out_bool(gboolean arg, gboolean *out);
void everymat_pass_out_gint8(gint8 arg, gint8 *out);
void everymat_pass_out_guint8(guint8 arg, guint8 *out);
void everymat_pass_out_gint16(gint16 arg, gint16 *out);
void everymat_pass_out_guint16(guint16 arg, guint16 *out);
void everymat_pass_out_gint32(gint32 arg, gint32 *out);
void everymat_pass_out_guint32(guint32 arg, guint32 *out);
void everymat_pass_out_gint64(gint64 arg, gint64 *out);
void everymat_pass_out_guint64(guint64 arg, guint64 *out);
void everymat_pass_out_gfloat(gfloat arg, gfloat *out);
void everymat_pass_out_gdouble(gdouble arg, gdouble *out);
void everymat_pass_out_string(char *arg, char **out);
void everymat_pass_out_gtype(GType arg, GType *out);
void everymat_pass_out_gobject(GObject *arg, GObject **out);

void everymat_pass_inout_bool(gboolean *arg);
void everymat_pass_inout_gint8(gint8 *arg);
void everymat_pass_inout_guint8(guint8 *arg);
void everymat_pass_inout_gint16(gint16 *arg);
void everymat_pass_inout_guint16(guint16 *arg);
void everymat_pass_inout_gint32(gint32 *arg);
void everymat_pass_inout_guint32(guint32 *arg);
void everymat_pass_inout_gint64(gint64 *arg);
void everymat_pass_inout_guint64(guint64 *arg);
void everymat_pass_inout_gfloat(gfloat *arg);
void everymat_pass_inout_gdouble(gdouble *arg);
void everymat_pass_inout_string(char **arg);
void everymat_pass_inout_gtype(GType *arg);
void everymat_pass_inout_gobject(GObject **arg);

gdouble everymat_prod(gdouble arg1, gdouble arg2);
gdouble everymat_weave(gboolean arg1, gint32 *out2, gdouble arg3, gint32 arg4, gboolean *out5);

gint64 * everymat_get_fixed_array();
gint64 * everymat_get_zero_term_array();
gboolean * everymat_pass_array_bool(gboolean * arg, gint len, gint *outlen);
gint8 * everymat_pass_array_gint8(gint8 * arg, gint len, gint *outlen);
guint8 * everymat_pass_array_guint8(guint8 * arg, gint len, gint *outlen);
gint16 * everymat_pass_array_gint16(gint16 * arg, gint len, gint *outlen);
guint16 * everymat_pass_array_guint16(guint16 * arg, gint len, gint *outlen);
gint32 * everymat_pass_array_gint32(gint32 * arg, gint len, gint *outlen);
guint32 * everymat_pass_array_guint32(guint32 * arg, gint len, gint *outlen);
gint64 * everymat_pass_array_gint64(gint64 * arg, gint len, gint *outlen);
guint64 * everymat_pass_array_guint64(guint64 * arg, gint len, gint *outlen);
gfloat * everymat_pass_array_gfloat(gfloat * arg, gint len, gint *outlen);
gdouble * everymat_pass_array_gdouble(gdouble * arg, gint len, gint *outlen);
char ** everymat_pass_array_string(char **arg, gint len, gint *outlen);
GType * everymat_pass_array_gtype(GType * arg, gint len, gint *outlen);

GArray * everymat_pass_garray_bool(GArray *arg);
GArray * everymat_pass_garray_gint8(GArray *arg);
GArray * everymat_pass_garray_guint8(GArray *arg);
GArray * everymat_pass_garray_gint16(GArray *arg);
GArray * everymat_pass_garray_guint16(GArray *arg);
GArray * everymat_pass_garray_gint32(GArray *arg);
GArray * everymat_pass_garray_guint32(GArray *arg);
GArray * everymat_pass_garray_gint64(GArray *arg);
GArray * everymat_pass_garray_guint64(GArray *arg);
GArray * everymat_pass_garray_gfloat(GArray *arg);
GArray * everymat_pass_garray_gdouble(GArray *arg);
GArray * everymat_pass_garray_string(GArray *arg);
GArray * everymat_pass_garray_gtype(GArray *arg);

GList * everymat_pass_glist_bool(GList *arg);
GList * everymat_pass_glist_gint8(GList *arg);
GList * everymat_pass_glist_guint8(GList *arg);
GList * everymat_pass_glist_gint16(GList *arg);
GList * everymat_pass_glist_guint16(GList *arg);
GList * everymat_pass_glist_gint32(GList *arg);
GList * everymat_pass_glist_guint32(GList *arg);
GList * everymat_pass_glist_gint64(GList *arg);
GList * everymat_pass_glist_guint64(GList *arg);
GList * everymat_pass_glist_gfloat(GList *arg);
GList * everymat_pass_glist_gdouble(GList *arg);
GList * everymat_pass_glist_string(GList *arg);
GList * everymat_pass_glist_gtype(GList *arg);

GSList * everymat_pass_gslist_bool(GSList *arg);
GSList * everymat_pass_gslist_gint8(GSList *arg);
GSList * everymat_pass_gslist_guint8(GSList *arg);
GSList * everymat_pass_gslist_gint16(GSList *arg);
GSList * everymat_pass_gslist_guint16(GSList *arg);
GSList * everymat_pass_gslist_gint32(GSList *arg);
GSList * everymat_pass_gslist_guint32(GSList *arg);
GSList * everymat_pass_gslist_gint64(GSList *arg);
GSList * everymat_pass_gslist_guint64(GSList *arg);
GSList * everymat_pass_gslist_gfloat(GSList *arg);
GSList * everymat_pass_gslist_gdouble(GSList *arg);
GSList * everymat_pass_gslist_string(GSList *arg);
GSList * everymat_pass_gslist_gtype(GSList *arg);

/******************** NOISY **********************/

#define EVERYMAT_TYPE_NOISY		(everymat_noisy_get_type())
#define EVERYMAT_NOISY(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), EVERYMAT_TYPE_NOISY, EverymatNoisy))
#define EVERYMAT_IS_NOISY(obj)	(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVERYMAT_TYPE_NOISY))
#define EVERYMAT_NOISY_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), EVERYMAT_TYPE_NOISY, EverymatNoisyClass))
#define EVERYMAT_IS_NOISY_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), EVERYMAT_TYPE_NOISY))
#define EVERYMAT_NOISY_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), EVERYMAT_TYPE_NOISY, EverymatNoisyClass))

typedef struct _EverymatNoisy EverymatNoisy;
typedef struct _EverymatNoisyClass EverymatNoisyClass;

struct _EverymatNoisy {
  GObject parent_instance;
};

struct _EverymatNoisyClass {
  GObjectClass parent_class;
};

GType everymat_noisy_get_type();

/******************** THING **********************/

#define EVERYMAT_TYPE_THING		(everymat_thing_get_type())
#define EVERYMAT_THING(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), EVERYMAT_TYPE_THING, EverymatThing))
#define EVERYMAT_IS_THING(obj)	(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVERYMAT_TYPE_THING))
#define EVERYMAT_THING_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), EVERYMAT_TYPE_THING, EverymatThingClass))
#define EVERYMAT_IS_THING_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), EVERYMAT_TYPE_THING))
#define EVERYMAT_THING_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), EVERYMAT_TYPE_THING, EverymatThingClass))

typedef struct _EverymatThing EverymatThing;
typedef struct _EverymatThingClass EverymatThingClass;

struct _EverymatThing {
  GObject parent_instance;
  gboolean prop_bool;
  gchar prop_char;
  guchar prop_uchar;
  gint prop_int;
  guint prop_uint;
  glong prop_long;
  gulong prop_ulong;
  gint64 prop_int64;
  guint64 prop_uint64;
  gfloat prop_float;
  gdouble prop_double;
  gchar * prop_string;
  GType prop_gtype;
  GObject *prop_object;
};

struct _EverymatThingClass {
  GObjectClass parent_class;
  guint thingy;
  guint count;
};

GType everymat_thing_get_type();

void everymat_thing_void(EverymatThing *obj);
gint everymat_thing_zero(EverymatThing *obj);
gdouble everymat_thing_one(EverymatThing *obj, gdouble arg1);
gdouble everymat_thing_two(EverymatThing *obj, gdouble arg1, gint arg2);
void everymat_thing_pass_out_gint32(EverymatThing *obj, gint32 arg, gint32 *out);
gdouble everymat_thing_weave(EverymatThing *obj, gboolean arg1, gint32 *out2, gdouble arg3, gint32 arg4, gboolean *out5);
gdouble everymat_thing_emit(EverymatThing *obj, gdouble arg);

guint everymat_thing_get_count();
GObject *everymat_thing_make_subthing(EverymatThing *obj);
GObject *everymat_thing_make_stored_subthing(EverymatThing *obj);
void everymat_thing_receive_object(EverymatThing *thing, GObject *obj, GObject *junk);
void everymat_thing_dup_object(EverymatThing *thing, GObject *obj, GObject *junk);

/******************** SUBTHING **********************/

#define EVERYMAT_TYPE_SUBTHING		(everymat_subthing_get_type())
#define EVERYMAT_SUBTHING(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), EVERYMAT_TYPE_SUBTHING, EverymatSubthing))
#define EVERYMAT_IS_SUBTHING(obj)	(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EVERYMAT_TYPE_SUBTHING))
#define EVERYMAT_SUBTHING_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), EVERYMAT_TYPE_SUBTHING, EverymatSubthingClass))
#define EVERYMAT_IS_SUBTHING_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), EVERYMAT_TYPE_SUBTHING))
#define EVERYMAT_SUBTHING_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), EVERYMAT_TYPE_SUBTHING, EverymatSubthingClass))

typedef struct _EverymatSubthing EverymatSubthing;
typedef struct _EverymatSubthingClass EverymatSubthingClass;

struct _EverymatSubthing {
  EverymatThing parent_instance;
};

struct _EverymatSubthingClass {
  EverymatThingClass parent_class;
};

GType everymat_subthing_get_type();

/******************** BOXTHING **********************/

#define EVERYMAT_TYPE_BOXTHING       (everymat_boxthing_get_type())

typedef struct
{
  gint value;
} EverymatBoxthing;

GType everymat_boxthing_get_type();
EverymatBoxthing *everymat_boxthing_new();
void everymat_boxthing_free(EverymatBoxthing *thing);
EverymatBoxthing *everymat_boxthing_copy(EverymatBoxthing *thing);
guint everymat_boxthing_count();
void everymat_boxthing_set(EverymatBoxthing *thing, gint val);
gint everymat_boxthing_get(EverymatBoxthing *thing);
